/**
 * Name: init_daemon.c
 * Author: zuoyanyouwu
 * init daemon
 */

#include "unp.h"
#include "daemon.h"

/* 捕捉发送的终止命令： kill(1) */   
static void sig_term(int signo) {
	time_t ticks;

	if(signo == SIGTERM) {
		ticks = time(NULL);
		syslog(LOG_INFO, "program terminated at %s", asctime(localtime(&ticks)));
		closelog();
		exit(0);
	}
}

void init_daemon(const char *pname, int facility) {
	int i; 
	pid_t pid; 
	
	/* 忽略或处理可能的终端信号 */
	signal(SIGTTOU,SIG_IGN);
	signal(SIGTTIN,SIG_IGN);
	signal(SIGTSTP,SIG_IGN);
	signal(SIGHUP,SIG_IGN);
	signal(SIGTERM, sig_term);

	if( (pid=fork()) > 0) 
		exit(0);  // 结束父进程 
	else if(pid< 0) 
		exit(1);  
	setsid();  // 第一子进程成为新的会话组长和进程组长, 与控制终端分离 
	if( (pid = fork()) > 0) 
		exit(0);  // 结束第一子进程 
	else if(pid < 0) 
		exit(1); 
	// 第二子进程，继续运行

	for(i = 0; i < NOFILE; ++i) // 关闭打开的文件描述符 
		close(i); 
	open("/dev/null",O_RDONLY);
	open("/dev/null",O_RDWR);
	open("/dev/null",O_RDWR);
	chdir("/tmp");  // 改变工作目录到/tmp 
	umask( 0);  // 重设文件创建掩模
	signal(SIGCHLD, SIG_IGN);  // 忽略子进程
	openlog(pname, LOG_CONS | LOG_PID, facility);

	return; 
} 
